package com.online.shopping.common.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.online.shopping.common.utils.CommonResult;
import com.online.shopping.common.utils.JwtTokenUtil;
import com.online.shopping.common.utils.UserDetailImpl;
import com.online.shopping.pojo.TbSeller;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

// 用户认证Filter
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

	private AuthenticationManager authenticationManager;

	public JwtAuthenticationFilter(String url, AuthenticationManager authenticationManager) {
		this.authenticationManager = authenticationManager;
		setFilterProcessesUrl(url);     // 指定用户认证的url
	}

	// 用户认证
	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

		try {
			// 获取前端json的数据（用户名和密码）
			TbSeller tbSeller = new ObjectMapper().readValue(request.getInputStream(), TbSeller.class);
			System.out.println("账号："+tbSeller.getSellerId());
			System.out.println("密码："+tbSeller.getPassword());

			// subject.login(token);
			return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(tbSeller.getSellerId(),tbSeller.getPassword(),new ArrayList<>()));

		} catch (IOException e) {
			e.printStackTrace();
			return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(null,null,new ArrayList<>()));
		}
	}

	// 认证成功的回调方法，主要是返回一个有效的jwt的token（令牌）
	@Override
	protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
		response.setContentType("application/json;charset=UTF-8");
		PrintWriter out = response.getWriter();

		// 获取认证的主体信息
		UserDetailImpl userDetail = (UserDetailImpl) authResult.getPrincipal();
		// 生成token
		String token = JwtTokenUtil.createToken("gec",userDetail.getUsername(),1800L);
		System.out.println(token);

		out.write(new ObjectMapper().writeValueAsString(CommonResult.success(JwtTokenUtil.TOKEN_PREFIX+token)));
		out.flush();
		out.close();
	}

	// 认证失败的回调方法
	@Override
	protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
		response.setContentType("application/json;charset=UTF-8");
		PrintWriter out = response.getWriter();

		System.out.println("failure exception："+failed.getMessage());

		out.write(new ObjectMapper().writeValueAsString(CommonResult.failed("登录失败！")));
		out.flush();
		out.close();
	}
}
